﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Comm;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Kinlo.Model;
using Kinlo.Repo;
using Kinlo.UI.Main.Hepler;
using Kinlo.UI.Main.Service;
using Kinlo.UI.Main.View;
using S7.Net;

namespace Kinlo.UI.Main.VM
{
    public class MainVM:ViewModelBase
    {
        MainWindow View;
        System.Timers.Timer timer = new System.Timers.Timer(2000);
        //System.Timers.Timer timer2 = new System.Timers.Timer(2000);

        AfterWeightFirstRep AFDB = new AfterWeightFirstRep(); 
        BeforWeightFirstRep BFDB = new BeforWeightFirstRep();
        CodeFirstRep CFDB = new CodeFirstRep();
        CounterRep CNTDB = new CounterRep();
        CoreService CoreService;
        public CounterNing countNing { get; set; }
        public MainVM(MainWindow view)
        {
            View = view;
            EventInfos = new ObservableCollection<string>();
            ScanBarcode = new ObservableCollection<CodeFirst>();
            FrontWeights = new ObservableCollection<BeforWeightFirst>();
            AfterWeights = new ObservableCollection<AfterWeightFirst>();
            countNing = CounterNing.Load();
   

            timer.Elapsed += Timer_Elapsed;
            timer.Enabled = true;
            //timer2.Elapsed += Timer2_Elapsed;
            //timer2.Enabled = true;
            Messenger.Default.Register<CodeFirst>(this, "SendCodeFirst", new Action<CodeFirst>((w) => AddCodeFirst(w)));
            Messenger.Default.Register<List<BeforWeightFirst>>(this, "SendBeforWeightFirst", new Action<List<BeforWeightFirst>>((w) => AddBeforWeightFirst(w)));
            Messenger.Default.Register<List<AfterWeightFirst>>(this, "SendAfterWeightFirst", new Action<List<AfterWeightFirst>>((w) => AddAfterWeightFirst(w)));
 
            Messenger.Default.Register<bool>(this, "SendPLCStatus", new Action<bool>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    PlcStatus = i; 
                }));
            }));

            Messenger.Default.Register<bool>(this, "SendDatabaseStatus", new Action<bool>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    DatabaseStatus = i; 
                }));
            }));
            Messenger.Default.Register<int>(this, "SendINCount", new Action<int>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    INCount = i; 
                }));
            }));
            Messenger.Default.Register<int>(this, "SendOutCount", new Action<int>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    OutCount = i; 
                }));
            }));
            Messenger.Default.Register<int>(this, "SendOKCount", new Action<int>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    OKCount = i;
                }));
            }));
            Messenger.Default.Register<int>(this, "SendNGCount", new Action<int>((i) => {
                this.View.Dispatcher.BeginInvoke(new Action(() => {
                    NGCount = i;
                }));
            }));
            Messenger.Default.Register<string>(this, "ReceiveEventInfo", new Action<string>((s) => {
                this.View.Dispatcher.BeginInvoke(new Action(() =>                {
                    var msg = DateTime.Now.ToString("HH:mm:ss") + " " + s;
                    EventInfos.Add(msg);
                    this.View.lstEvent.ScrollIntoView(msg);
                    RaisePropertyChanged(() => EventInfos);
                }));
            }));

            Messenger.Default.Register<string>(this, "CmdUpdateBatchNo", new Action<string>((i) => {
                BatchNo = GlobalValues.BatchNo;
            }));
            var addr= ConfigurationManager.AppSettings["Ipaddr"];
            PlcAddr = addr;
            CoreService = new CoreService(countNing);

            BatchNo = GlobalValues.BatchNo;
        }

        //private void Timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        //{
        //   var data= AFDB.GetAfterFirst("2018-10-25 15:44:56.540", "2019-01-01 00:00:00", "%", "%");
        //    foreach(var d in data)
        //    {
        //        AddAfterWeightFirst(d);
        //    }
        //}

        void AddCodeFirst(CodeFirst w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                try
                {
                    ScanBarcode.Add(w);
                    this.View.datagridview1.ScrollIntoView(w);
                }
                catch { }
            }));
        }
        void AddBeforWeightFirst(List<BeforWeightFirst> w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() => {
                try
                {
                    if (w != null && w.Count > 0)
                    {
                        foreach (var w1 in w)
                        {
                            FrontWeights.Add(w1);
                            this.View.datagridview2.ScrollIntoView(w1);
                        }
                    }
                }
                catch { }
            }));
        }
        void AddAfterWeightFirst(List<AfterWeightFirst> w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() => {
                try
                {

                if(w!=null&&w.Count>0)
                {
                    foreach(var w1 in w)
                    {
                        AfterWeights.Add(w1);
                        this.View.datagridview3.ScrollIntoView(w1);
                    }
                    }
                }
                catch { }
            }));
        } 

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {  
        }

        string plcAddr;
        /// <summary>
        /// PLC地址
        /// </summary>ww
        public string PlcAddr
        {
            get { return plcAddr; }
            set
            {
                plcAddr = value;
                RaisePropertyChanged(() => PlcAddr);
            }
        }
        bool plcStatus;
        /// <summary>
        /// PLC状态
        /// </summary>
        public bool PlcStatus
        {
            get { return plcStatus; }
            set
            {
                plcStatus = value;
                RaisePropertyChanged(() => PlcStatus); 
            }
        }
        bool databaseStatus;
        /// <summary>
        /// 数据库状态
        /// </summary>
        public bool DatabaseStatus
        {
            get { return databaseStatus; }
            set
            {
                databaseStatus = value;
                RaisePropertyChanged(() => DatabaseStatus);
            }
        }

        string batchNo;
        /// <summary>
        ///批次号
        /// </summary>
        public string BatchNo
        {
            get { return batchNo; }
            set
            {
                batchNo = value;
                RaisePropertyChanged(() => BatchNo);
            }
        }

        int inCount;
        /// <summary>
        /// 投入
        /// </summary>
        public int INCount
        {
            get { return inCount; }
            set
            {
                inCount = value;
                
                RaisePropertyChanged(() => INCount);
            }
        }
        int outCount;
        /// <summary>
        /// 产出
        /// </summary>
        public int OutCount
        {
            get { return outCount; }
            set
            {
                outCount = value;
                RaisePropertyChanged(() => OutCount); 
            }
        }
        int okCount;
        /// <summary>
        /// 合格数
        /// </summary>
        public int OKCount
        {
            get { return okCount; }
            set
            {
                okCount = value;
                RaisePropertyChanged(() => OKCount);
                RaisePropertyChanged("QualifiRate");
                QualifiRate = "";
            }
        }
        int ngCount;
        /// <summary>
        /// 不合格数
        /// </summary>
        public int NGCount
        {
            get { return ngCount; }
            set
            {
                ngCount = value;
                RaisePropertyChanged(() => NGCount);
                QualifiRate = "";
            }
        }
        string qualifiRate;
        /// <summary>
        /// 合格率
        /// </summary>
        public string QualifiRate
        {
            get { return qualifiRate; }
            set
            {
                qualifiRate = (OKCount/(OKCount+NGCount+0.0001)).ToString("P2");
                RaisePropertyChanged(()=>QualifiRate);
            }
        }

        ObservableCollection<string> eventInfos;
        /// <summary>
        /// 日志信息
        /// </summary>
        public ObservableCollection<string> EventInfos
        {
            get { return eventInfos; }
            set
            {
                eventInfos = value;
                RaisePropertyChanged(() => EventInfos);
            }
        }
        ObservableCollection<CodeFirst> scanBarcode;
        /// <summary>
        /// 前扫码
        /// </summary>
        public ObservableCollection<CodeFirst>ScanBarcode
        {
            get { return scanBarcode; }
            set
            {
                scanBarcode = value;
                RaisePropertyChanged(() => ScanBarcode);
            }
        }
        ObservableCollection<BeforWeightFirst> frontWeights;
        /// <summary>
        /// 前称重
        /// </summary>
        public ObservableCollection<BeforWeightFirst> FrontWeights
        {
            get { return frontWeights; }
            set
            {
                frontWeights = value;
                RaisePropertyChanged(() => FrontWeights);
            }
        }
        ObservableCollection<AfterWeightFirst> afterWeights;
        /// <summary>
        /// 后称重
        /// </summary>
        public ObservableCollection<AfterWeightFirst> AfterWeights
        {
            get { return afterWeights; }
            set
            {
                afterWeights = value;
                RaisePropertyChanged(() => AfterWeights);
            }
        }
        RelayCommand cmdConnectPlc;
        /// <summary>
        /// 连接PLC
        /// </summary>
        public RelayCommand CmdConnectPlc
        {
            get { return cmdConnectPlc ?? (cmdConnectPlc = new RelayCommand(() => DoCmdConnectPlc())); }
        }
        void DoCmdConnectPlc()
        {
            try
            {
                Logger.Log.Info("start");
                CoreService.Start();
            }
            catch(Exception ex)
            {

            }
        }
        RelayCommand cmdBatchInput;
        /// <summary>
        /// 电解液批次录入
        /// </summary>
        public RelayCommand CmdBatchInput
        {
            get { return cmdBatchInput ?? (cmdBatchInput = new RelayCommand(() => DoCmdBatchInput())); }
        }
        void DoCmdBatchInput()
        {
            var win = new BatchInputView();
            win.ShowDialog();
        }

        RelayCommand cmdQuery;
        /// <summary>
        /// 查询
        /// </summary>
        public RelayCommand CmdQuery
        {
            get { return cmdQuery ?? (cmdQuery = new RelayCommand(() => DoCmdQuery())); }
        }
        void DoCmdQuery()
        {
            var win = new QueryView();
            win.ShowDialog();
        }

        RelayCommand cmdMesSetting;
        /// <summary>
        /// 查询
        /// </summary>
        public RelayCommand CmdMesSetting
        {
            get { return cmdMesSetting ?? (cmdMesSetting = new RelayCommand(() => DoCmdMesSetting())); }
        }
        void DoCmdMesSetting()
        {
            var win = new MesSettingView();
            win.ShowDialog();
        }
        //

        RelayCommand cmdCounterClear;
        /// <summary>
        /// 计算清零
        /// </summary>
        public RelayCommand CmdCounterClear
        {
            get { return cmdCounterClear ?? (cmdCounterClear = new RelayCommand(() => DoCmdCounterClear())); }
        }
        void DoCmdCounterClear()
        {
            if (MessageBox.Show("确认要清零计数器", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                //清零产量
                try
                {
                    CoreService.ClearZero();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("清除产量失败，请先连接PLC");
                }


                countNing.ClearZero();
                Logger.Log.Info("清零成功！！！");
                var insertCode= CNTDB.InsertCounterBak(); 
                if (insertCode > 0) {

                    Logger.Log.Info(string.Format("计数器备份成功:[{4}]:InCount:{0},OutCount:{1},OKCount:{2},NGCount:{3}", CoreService.InCount,
                        CoreService.OutCount, CoreService.OKCount, CoreService.NGCount,DateTime.Now));
                }
                else
                {
                    Logger.Log.Info(string.Format("计数器备份失败:[{4}]:InCount:{0},OutCount:{1},OKCount:{2},NGCount:{3}", CoreService.InCount,
                        CoreService.OutCount, CoreService.OKCount, CoreService.NGCount, DateTime.Now));
                }
               var result = CNTDB.ClearCounter();

                Logger.Log.Info($"清零前产量：投入:{countNing.INCount},产出:{countNing.OUTCount},OK数量:{countNing.OKCount},NG数量:{countNing.NGCount},合格率:{countNing.QualifiedCountRate}");
           
                if (result > 0)
                {
                    INCount = 0;
                    OutCount = 0;
                    OKCount = 0;
                    NGCount = 0;
                    Interlocked.Exchange(ref CoreService.InCount, 0);
                    Interlocked.Exchange(ref CoreService.OutCount, 0);
                    Interlocked.Exchange(ref CoreService.OKCount, 0);
                    Interlocked.Exchange(ref CoreService.NGCount, 0);

                    //Messenger.Default.Send<int>(0, "SendToPlcClear"); 
                }
                else
                {
                    MessageBox.Show("计数清零失败", "错误");
                }

              

            }
        }

        RelayCommand<DataGridRowEventArgs> cmdLoadingRow;
        public RelayCommand<DataGridRowEventArgs> CmdLoadingRow
        {
            get { return cmdLoadingRow ?? (cmdLoadingRow = new RelayCommand<DataGridRowEventArgs>((e) => DoCmdLoadingRow(e))); }
        }
        void DoCmdLoadingRow(DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;
        }


        RelayCommand<CancelEventArgs> cmdMainClosing;
        public RelayCommand<CancelEventArgs> CmdMainClosing
        {
            get { return cmdMainClosing ?? (cmdMainClosing = new RelayCommand<CancelEventArgs>((e) => DoCmdMainClosing(e))); }
        }
        void DoCmdMainClosing(CancelEventArgs e)
        {
            try
            {
                if (MessageBox.Show("系统正在远行中，确认要关闭系统", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                {
                    Logger.Log.Info(string.Format("{0} 关闭系统",DateTime.Now));
                    e.Cancel = false; 
                }
                else
                {
                    e.Cancel = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("关闭系统发生异常:{0}", ex), "错误");
            }
        }
    }
}
